<?php

namespace LaiHe\LaravelHelper\Exceptions;

use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Database\QueryException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Response;
use Illuminate\Validation\ValidationException;

class Handler extends ExceptionHandler
{
	/**
	 * @param Exception $e
	 *
	 * @return mixed|void
	 * @throws Exception
	 */
	public function report(Exception $e)
	{
		if(is_callable($reportCallable = [$e, 'report'])){
			return $this->container->call($reportCallable);
		}
		$message = $e->getMessage() ?: class_basename($e);
		$data    = array_merge($this->context(), [
			'url'   => Request::url(),
			'query' => Request::except(['__token']),
			'class' => get_class($e),
			'file'  => $e->getFile(),
			'line'  => $e->getLine(),
			'json'  => json_last_error(),
			'e'     => substr($e->getTraceAsString(), 0, $this->shouldntReport($e) ? 200 : -1),
		]);


		try{
			Log::channel('error')->error($message, $data);
		}catch(Exception $ex){
			Log::error($message, $data);
		}
	}

	/**
	 * @param \Illuminate\Http\Request $request
	 * @param Exception                $exception
	 *
	 * @return \Symfony\Component\HttpFoundation\Response
	 */
	public function render($request, Exception $exception)
	{
		$message  = $exception->getMessage() ?: class_basename($exception);
		$code     = $exception->getCode();
		$redirect = NULL;
		if($exception instanceof ValidationException){
			$message = implode('<br/>', $exception->validator->getMessageBag()->all());
		}
		if($exception instanceof AuthenticationException){
			$code     = 401;
			$message  = '您还未登录';
			$redirect = $exception->redirectTo();
			if(!$request->expectsJson()){
				Redirect::setIntendedUrl($request->fullUrl());
			}
		}
		if($exception instanceof ModelNotFoundException){
			$message = class_basename($exception->getModel()) . ':' . '资源信息出错';
		}
		if($exception instanceof QueryException){
			$message = '数据库错误';
			$code    = 1000;
		}
		if($exception instanceof AuthorizationException){
			$code    = 403;
			$message = '您没有权限进行这个操作';
		}

		return Response::error($message, $redirect, $code);
	}
}
